﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WPFByCoreApp
{
    /// <summary>
    /// Interaction logic for TestDrawCanvasWindow.xaml
    /// </summary>
    public partial class TestDrawingVisualWindow : Window
    {
        MyElement1 element1;

        public TestDrawingVisualWindow()
        {
            InitializeComponent();

            element1 = new MyElement1(this);

            this.grid1.Children.Add(element1);
            this.Loaded += TestDrawingVisualWindow_Loaded;
        }

        private void TestDrawingVisualWindow_Loaded(object sender, RoutedEventArgs e)
        {
            element1.DealData();
        }
    }

    public class MyElement1 : Grid
    {
        private MyBorder1[] myBorders;

        private int MaxBorder = 4;

        public MyElement1(Window w)
        {
            int ColNum = 4;
            int RowNum = MaxBorder / ColNum;

            for (int i = 0; i < RowNum; i++)
            {
                this.RowDefinitions.Add(new RowDefinition());
            }

            for (int i = 0; i < ColNum; i++)
            {
                this.ColumnDefinitions.Add(new ColumnDefinition());
            }


            myBorders = new MyBorder1[MaxBorder];

            int ColIndex = 0;
            int RowIndex = 0;

            for (int i = 0; i < myBorders.Length; i++)
            {
                myBorders[i] = new MyBorder1();
                this.Children.Add(myBorders[i]);
                Grid.SetRow(myBorders[i], RowIndex);
                Grid.SetColumn(myBorders[i], ColIndex);

                ColIndex++;

                if (ColIndex > (ColNum - 1))
                {
                    ColIndex = 0;
                    RowIndex++;
                }
            }
        }

        public void DealData()
        {

            Task.Run(delegate
            {
                while (true)
                {

                    foreach (var border1 in myBorders)
                    {
                        border1.Init();
                    }

                    Thread.Sleep(100);
                }
            });

            Task.Run(delegate
            {
                while (true)
                {
                    this.Dispatcher.Invoke((Action)delegate
                    {
                        foreach (var border1 in myBorders)
                        {

                            border1.InvalidateVisual();

                            //Thread.Sleep(1);
                        }
                    }, System.Windows.Threading.DispatcherPriority.SystemIdle);


                    Thread.Sleep(40);
                }
            });
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                //Point p = e.GetPosition(this);
                //foreach (var border in myBorders)
                //{
                //    if (border.IsIn(p))
                //        border.IsSelected = true;
                //    else
                //        border.IsSelected = false;
                //}

            }

            base.OnMouseDown(e);
        }
    }

    public class MyBorder1 : Border
    {
        public Point[] traces;

        public bool IsSelected;

        static Random random = new Random();

        //private DrawingVisual _drawingVisual;

        private PathGeometry pathGeometry;

        private Brush brush;

        private Pen pen;

        private Pen pen1;

        private Rect rect;

        public MyBorder1()
        {
            traces = new Point[2000];

            rect = new Rect();
            brush = new SolidColorBrush(Colors.Red);
            pen = new Pen(new SolidColorBrush(Colors.Gray), 3);
            pen1 = new Pen(new SolidColorBrush(Colors.Red), 3);
            //_drawingVisual = new DrawingVisual();
            pathGeometry = new PathGeometry();
            PathFigure pathFigure = new PathFigure();

            LineSegment line = new LineSegment();

      


            for (int i = 0; i < traces.Count(); i++)
            {
                if (i == 0)
                {
                    pathFigure.StartPoint = traces[i];
                    pathFigure.IsClosed = false;
                }
                else
                {
                    pathFigure.Segments.Add(new LineSegment(traces[i], false));
                }
            }

            pathGeometry.Figures.Add(pathFigure);

            //this.AddVisualChild(_drawingVisual);

            this.BorderBrush = new SolidColorBrush(Colors.Red);
            this.BorderThickness = new Thickness(1);

            this.Margin = new Thickness(3);

            polyline.Stroke = Brushes.Black;
            polyline.StrokeThickness = 1;


            for (int i = 0; i < traces.Count(); i++)
            {
                polyline.Points.Add(traces[0]);
            }


            this.Child = polyline;
        }

        bool IsInit = false;

        public void Init()
        {
            //if (!IsInit)
            for (int i = 0; i < traces.Length; i++)
            {
                //traces[i] = ActualHeight == 0 ? new Point() : new Point((i * 20), Math.Sin(i * 0.1) * 100 + random.Next(0, (int)ActualHeight));
                //traces[i + 1] = ActualHeight == 0 ? new Point() : new Point((i + 10) * 2, Math.Sin((i + 1) * 0.1) * 100 + random.Next(0, (int)ActualHeight));
                traces[i].X = i <= (int)(rect.Width) ? i : (int)(rect.Width);
                traces[i].Y = random.Next(0, (int)(rect.Height));
            }

            IsInit = true;
        }

        Stopwatch w = new Stopwatch();

        Polyline polyline = new Polyline();

        protected override void OnRender(DrawingContext drawingContext)
        {
            w.Restart();
            rect.Width = this.ActualWidth;
            rect.Height = this.ActualHeight;


       

     
            //DrawingContext dc = _drawingVisual.RenderOpen();

            DrawingContext dc = drawingContext;

            if (pathGeometry != null)
            {
                //var pathFigure = pathGeometry.Figures[0];

                for (int i = 0; i < traces.Count(); i++)
                {
                    polyline.Points[i] = traces[i];
                    //if (i == 0)
                    //{
                    //    pathFigure.StartPoint = traces[i];
                    //    pathFigure.IsClosed = false;
                    //}
                    //else
                    //{
                    //    ((LineSegment)pathFigure.Segments[i - 1]).Point = traces[i];
                    //}
                }

                //dc.DrawGeometry(Brushes.Black, null, polyline.RenderedGeometry);

            }



            base.OnRender(drawingContext);

            w.Stop();

            Debug.WriteLine("OnRender----Stopwatch:" + w.ElapsedMilliseconds);
        }

        //protected override int VisualChildrenCount => 1;

        //protected override Visual GetVisualChild(int index)
        //{
        //    if (index == 0)
        //        return _drawingVisual;

        //    return base.GetVisualChild(index);
        //}
    }
}
